type op =
    Add
  | Sub
  | Mult
  | Div
  | Equal
  | Neq
  | Less
  | Leq
  | Greater
  | Geq
  | And
  | Or
  | Mod
type expr =
    Id of string
  | IntLiteral of int
  | BoolLiteral of bool
  | Binop of expr * op * expr
  | Assign of expr * expr
  | Call of string * expr list
  | Noexpr
  | Not of expr
  | StringLiteral of string
  | CardLiteral of string
  | ListLiteral of expr list
  | LabelLiteral of string
type stmt =
    Expr of expr
  | Return of expr
  | If of expr * stmt * stmt
  | Block of stmt list
  | For of expr * expr * expr * stmt
  | While of expr * stmt
type var_decl = { varname : string; vartype : string; }
type func_decl = {
  fname : string;
  freturn : string;
  formals : var_decl list;
  locals : var_decl list;
  body : stmt list;
}
type program = var_decl list * func_decl list
val string_of_expr : expr -> string
val string_of_stmt : stmt -> string
val string_of_var_decl : var_decl -> string
val string_of_fdecl : func_decl -> string
val string_of_program : var_decl list * func_decl list -> string
